import java_cup.runtime.Symbol;

%%

%line
%char
%cup
%state COMMENT

digit = [0-9]
number = {digit}+
float = {number}\.{number}
letter = [a-zA-Z]
character = {digit}|{letter}
char = (\'({character})\') 
string = (\"({character}|[ \t_])*\")
identifier = {letter}({character})*
whitespace = [ \t\r\n\f]

%%
<YYINITIAL>	";" {return new Symbol(sym.SEMI, yyline, yychar);}

<YYINITIAL> "str" {return new Symbol(sym.STR_TYPE, yyline, yychar);}
<YYINITIAL> "int" {return new Symbol(sym.INT_TYPE, yyline, yychar);}
<YYINITIAL> "float" {return new Symbol(sym.FLOAT_TYPE, yyline, yychar);}
<YYINITIAL> "char" {return new Symbol(sym.CHAR_TYPE, yyline, yychar);}
<YYINITIAL> "bool" {return new Symbol(sym.BOOL_TYPE, yyline, yychar);}
<YYINITIAL> "tuple" {return new Symbol(sym.TUPLE_TYPE, yyline, yychar);}
<YYINITIAL> "list" {return new Symbol(sym.LIST_TYPE, yyline, yychar);}

<YYINITIAL> "tdef" {return new Symbol(sym.TDEF, yyline, yychar);}

<YYINITIAL> {number} {return new Symbol(sym.INT, yyline, yychar, new Integer(yytext()));}
<YYINITIAL> {float} {return new Symbol(sym.FLOAT, yyline, yychar, new Float(yytext()));}

<YYINITIAL> {char} { return new Symbol(sym.CHAR, yyline, yychar, yytext());}
<YYINITIAL> {string} {
	return new Symbol(sym.STRING, yyline, yychar, yytext().replaceAll("\"", ""));}

<YYINITIAL> "true" {return new Symbol(sym.TRUE, yyline, yychar);}
<YYINITIAL> "false" {return new Symbol(sym.FALSE, yyline, yychar);}

<YYINITIAL> "+" {return new Symbol(sym.PLUS, yyline, yychar);}
<YYINITIAL> "*" {return new Symbol(sym.TIMES, yyline, yychar);}
<YYINITIAL> "-" {return new Symbol(sym.MINUS, yyline, yychar);}
<YYINITIAL> "/" {return new Symbol(sym.DIVIDE, yyline, yychar);}
<YYINITIAL> "^" {return new Symbol(sym.POWER, yyline, yychar);}

<YYINITIAL> "!" {return new Symbol(sym.NOT, yyline, yychar);}
<YYINITIAL> "||" {return new Symbol(sym.OR, yyline, yychar);}
<YYINITIAL> "&&" {return new Symbol(sym.AND, yyline, yychar);}

<YYINITIAL> "in" {return new Symbol(sym.IN, yyline, yychar);}
<YYINITIAL> "not in" {return new Symbol(sym.NOT_IN, yyline, yychar);}
<YYINITIAL> "::" {return new Symbol(sym.CONCAT, yyline, yychar);}
<YYINITIAL> "len" {return new Symbol(sym.LENGTH, yyline, yychar);}

<YYINITIAL> "<" {return new Symbol(sym.LESS, yyline, yychar);}
<YYINITIAL> "<=" {return new Symbol(sym.LESS_OR_EQUAL, yyline, yychar);}
<YYINITIAL> ">" {return new Symbol(sym.GREATER, yyline, yychar);}
<YYINITIAL> ">=" {return new Symbol(sym.GREATER_OR_EQUAL, yyline, yychar);}
<YYINITIAL> "==" {return new Symbol(sym.EQUAL, yyline, yychar);}
<YYINITIAL> "!=" {return new Symbol(sym.NOT_EQUAL, yyline, yychar);}

<YYINITIAL> "if" {return new Symbol(sym.IF, yyline, yychar);}
<YYINITIAL> "else" {return new Symbol(sym.ELSE, yyline, yychar);}

<YYINITIAL> "while" {return new Symbol(sym.WHILE, yyline, yychar);}
<YYINITIAL> "do" {return new Symbol(sym.DO, yyline, yychar);}

<YYINITIAL> "repeat" {return new Symbol(sym.REPEAT, yyline, yychar);}
<YYINITIAL> "until" {return new Symbol(sym.UNTIL, yyline, yychar);}

<YYINITIAL> "fdef" {return new Symbol(sym.FDEF, yyline, yychar);}
<YYINITIAL> "void" {return new Symbol(sym.VOID, yyline, yychar);}
<YYINITIAL> "return" {return new Symbol(sym.RETURN, yyline, yychar);}

<YYINITIAL> "[" {return new Symbol(sym.LSQUARE, yyline, yychar);}
<YYINITIAL> "]" {return new Symbol(sym.RSQUARE, yyline, yychar);}
<YYINITIAL> "{" {return new Symbol(sym.LBRACE, yyline, yychar);}
<YYINITIAL> "}" {return new Symbol(sym.RBRACE, yyline, yychar);}
<YYINITIAL> "(" {return new Symbol(sym.LPAREN, yyline, yychar);}
<YYINITIAL> ")" {return new Symbol(sym.RPAREN, yyline, yychar);}
<YYINITIAL> "=" {return new Symbol(sym.ASSIGN, yyline, yychar);}
<YYINITIAL> "." {return new Symbol(sym.PERIOD, yyline, yychar);}
<YYINITIAL> "," {return new Symbol(sym.COMMA, yyline, yychar);}
<YYINITIAL> "[|" {return new Symbol(sym.LTUPLE, yyline, yychar);}
<YYINITIAL> "|]" {return new Symbol(sym.RTUPLE, yyline, yychar);}
<YYINITIAL> ":" {return new Symbol(sym.COLON, yyline, yychar);}

<YYINITIAL> "/*" {yybegin(COMMENT);}
<COMMENT> "*/" {yybegin(YYINITIAL);}
<COMMENT>. {}
<COMMENT> {whitespace} {}

<YYINITIAL> {identifier} {return new Symbol(sym.ID, yyline, yychar, yytext());}
<YYINITIAL> {whitespace} {}

<YYINITIAL>. {System.out.println("error: unknown character " + yytext() + " found at line " + yyline);}